package com.qzw.common.service;

import com.qzw.common.api.base.*;
import com.qzw.common.data.BaseMysqlDao;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @author ：quziwei
 * @date ：Created in 2020/6/1 11:09 上午
 * @description：BaseServiceImpl
 */
public abstract class BaseServiceImpl<M extends BaseModel, E, ID extends Serializable, Q extends BaseQuery> implements BaseService<M, ID, Q> {


    protected abstract BaseMysqlDao getDao();

    protected abstract E model2Entity(M model);

    protected abstract M entity2model(E entity);

    protected boolean isNotEmpty(Object obj) {
        return !ObjectUtils.isEmpty(obj);
    }

    protected E getEntity(Optional<E> optional){
        return optional.get();
    }

    protected List<M> entity2Model(Collection<E> list) {
        List<M> mList = new ArrayList<>();
        list.forEach(e -> mList.add(entity2model(e)));
        return mList;
    }

    protected PageResp<M> page2pageResp(Page<E> page) {
        PageResp<M> pageResp = new PageResp<>();
        List<E> eList = page.getContent();
        List<M> mList = new ArrayList<>();
        pageResp.setList(mList);
        eList.forEach(e -> mList.add(entity2model(e)));
        pageResp.setPageNumber(page.getNumber() + 1);
        pageResp.setPageSize(page.getSize());
        pageResp.setTotalPage(page.getTotalPages());
        pageResp.setTotalRow(page.getTotalElements());
        return pageResp;
    }

    @Override
    @Transactional
    public M add(M m) {
        if (!isNotEmpty(m.getId())) {
            E entity = model2Entity(m);
            return entity2model((E) getDao().save(entity));
        }
        return null;
    }

    @Override
    public M update(M m) {
        if (isNotEmpty(m.getId())){
            E entity = model2Entity(m);
            return entity2model((E)getDao().save(entity));
        }
        return null;
    }

    @Override
    public M findById(ID id) {
        return entity2model((E) (getDao().findById(id)).get());
    }

    @Override
    public M findOne(M m) {
        return entity2model((E) getEntity((getDao().findOne(Example.of(model2Entity(m))))));
    }

    @Override
    public void deleteById(ID id) {
        getDao().deleteById(id);
    }

    @Override
    public void deleteOne(M m) {
        getDao().delete(model2Entity(m));
    }

    @Override
    public List<M> findAll() {

        return entity2Model(getDao().findAll());
    }

    @Override
    public List<M> findAll(M m) {
        return entity2Model(getDao().findAll(Example.of(model2Entity(m))));
    }

    @Override
    public PageResp<M> findAll(PageReq pageReq) {
        PageRequest pageRequest = PageRequest.of(pageReq.getPageNumber() - 1, pageReq.getPageSize(), Sort.by(Sort.Direction.DESC,"id"));
        Page<E> page = getDao().findAll(pageRequest);
        return page2pageResp(page);
    }

    @Override
    public PageResp<M> findAll(M m, PageReq pageReq) {
        PageRequest pageRequest = PageRequest.of(pageReq.getPageNumber() - 1, pageReq.getPageSize(), Sort.by(Sort.Direction.DESC,"id"));
        Page<E> page = getDao().findAll(Example.of(model2Entity(m)),pageRequest);
        return page2pageResp(page);
    }

    @Override
    public PageResp<M> findAll(Q q, PageReq pageReq) {
        new BaseException("method mast not be null!!!!!");
        return null;
    }
}
